#include "cmd_cp.h"

int operate_cp(command_t* cmd){
	if(cmd->cmd_argc!=2)return -1;
	fileInfo_t file;
	
	cmd_cp_parse_srcpath(cmd,&file);
	
	if(!file_isExist(file.src_file_name))return -1;

	FILE_TYPE ft=cmd_cp_parse_filetype(&file);
	file.ft=ft;
	return cmd_cp_exec(&file,cmd);
}
int cmd_cp_exec(fileInfo_t* file,command_t* cmd){
	FILE_TYPE ft=file->ft;
	int i=-1;
	switch(ft){
		case FT_FILE:
			i= cmd_cp_file(*file,cmd->cmd_params[1]);
			break;
		case FT_DIR:
			i=cmd_cp_dir(*file,cmd->cmd_params[1]);
			break;
		case FT_OTHER:
			break;
		case FT_ERROR:
			break;
	}
	return i;
}
int cmd_cp_dir(fileInfo_t file,char* dest){
	if(file.ft==FT_FILE)return cmd_cp_file(file,dest);
	DIR* dir=opendir(file.src_file_name);
	if(NULL==dir)return -1;
	char* newSrcPath=strcat(file.src_file_name,"/");
	char* newDestPath=strcat(dest,"/");
	if(access(newDestPath,F_OK)==-1){
		if(mkdir(newDestPath,0777)==-1)return -1;
	}
	struct dirent* dirent;
	while((dirent=readdir(dir))!=NULL){
		if(strcmp(dirent->d_name,".")==0||strcmp(dirent->d_name,"..")==0)continue;
		char curStrPath[512]={0};
		strcpy(curStrPath,newSrcPath);
		char curDestPath[512]={0};
		strcpy(curDestPath,newDestPath);

		strcat(curStrPath,dirent->d_name);
		strcat(curDestPath,dirent->d_name);
		fileInfo_t fi;
		strcpy(fi.src_file_name,curStrPath);
		fi.ft=cmd_cp_parse_filetype(&fi);
		cmd_cp_dir(fi,curDestPath);
	}
	closedir(dir);
	return 1;
}
int cmd_cp_file(fileInfo_t file,char* dest){
	FILE* srcFile=fopen(file.src_file_name,"r");
	if(NULL == srcFile)return -1;
	FILE* destFile=fopen(dest,"w+");
	if(NULL == destFile)return -1;
	char buf[256]={0};
	ssize_t byte=0;
	while((byte=fread(buf,1,sizeof(buf),srcFile))!=0){
		fwrite(buf,1,byte,destFile);
	}
	fclose(srcFile);
	return 1;
}

void cmd_cp_parse_srcpath(command_t* cmd,fileInfo_t* file){
	strcpy(file->src_file_name,cmd->cmd_params[0]);
}
FILE_TYPE cmd_cp_parse_filetype(fileInfo_t* file){
	struct stat statbuf;
	if(stat(file->src_file_name,&statbuf)==-1)return FT_ERROR;
	mode_t mode =statbuf.st_mode;
	if(S_ISREG(mode)){
		return FT_FILE;
	}else if(S_ISDIR(mode)){
		return FT_DIR;	
	}else{
		return FT_OTHER;
	} 
}
int file_isExist(char* name){
	return  access(name,F_OK)==0?1:0;
}
